package com.uatair.common.tcp.client;

import com.google.protobuf.CodedInputStream;
import com.google.protobuf.CodedOutputStream;
import com.uatair.common.tcp.util.TianjinTcp;
import com.uatair.common.tcp.util.TianjinTcp.Message;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.ByteBuffer;

@Component
public class TianJinClientService {

    private static final Logger logger = LoggerFactory.getLogger(TianJinClientService.class);

    private static final String serverIp = "123.59.7.55";
    private static final int serverPort = 29325;
    private static final String username = "914403003116581250";
    private static final String password = "2b095e982563f55148219948689a1da6";

    private Socket socket;
    private OutputStream outputStream;
    private InputStream inputStream;

    /**
     * 初始化连接
     */
    public synchronized void initConnection() throws IOException {
        if (socket == null || socket.isClosed()) {
            socket = new Socket(serverIp, serverPort);
            outputStream = socket.getOutputStream();
            inputStream = socket.getInputStream();

            logger.info("成功连接到天津无人机服务器: {}:{}", serverIp, serverPort);

            // 登录认证
            login();
        }
    }

    /**
     * 登录认证
     */
    private void login() throws IOException {
        TianjinTcp.LoginInfo loginInfo = TianjinTcp.LoginInfo.newBuilder()
                .setUserName(username)
                .setPassword(password)
                .build();

        Message message = Message.newBuilder()
                .setDataType(Message.DataType.LOGININFOTYPE)
                .setVersion(Message.ProtocolVersion.V1_0_1)
                .setLoginInfo(loginInfo)
                .build();

        sendMessage(message);

        // 读取登录响应
       /* Message response = readResponse();
        if (response.getDataType() == Message.DataType.LOGINRESPONSETYPE) {
            TianjinTcp.LoginResponse loginResponse = response.getLoginResponse();
            if (loginResponse.getCode() == 0) {
                logger.info("登录成功: {}", loginResponse.getMsg());
            } else {
                logger.error("登录失败: {}", loginResponse.getMsg());
                throw new IOException("登录认证失败: " + loginResponse.getMsg());
            }
        } else {
            throw new IOException("收到非预期的响应类型");
        }*/
    }

    /**
     * 发送消息
     */
    public void sendMessage(Message message) throws IOException {
        if (socket == null || socket.isClosed()) {
            initConnection();
        }

//        byte[] data = message.toByteArray();
//        outputStream.write(data);
//        outputStream.flush();

        // 使用 varint32 编解码器
        CodedOutputStream output = CodedOutputStream.newInstance(outputStream);
        CodedInputStream input = CodedInputStream.newInstance(inputStream);

        // 使用 varint32 格式发送消息
        output.writeUInt32NoTag(message.getSerializedSize());
        message.writeTo(output);
        output.flush();
        if(message.getDataType() == Message.DataType.LOGININFOTYPE) {
            // 接收登录响应 (使用 varint32 格式)
            int responseSize = input.readRawVarint32();

            byte[] responseBytes = input.readRawBytes(responseSize);
            Message loginResponse = Message.parseFrom(responseBytes);

            if (loginResponse.hasLoginResponse() && loginResponse.getLoginResponse().getCode() == 0) {
                logger.info("✅ 登录成功! 响应消息: {}", loginResponse.getLoginResponse().getMsg());
            } else {
                logger.error("❌ 登录失败! 错误代码: {}", loginResponse.hasLoginResponse() ? loginResponse.getLoginResponse().getCode() : "未知");
                return;
            }
        }
        logger.info("无人机数据上传成功: {}", message.toString().replaceAll("\\s+", ""));
    }

    /**
     * 读取响应
     */
    private Message readResponse() throws IOException {
        byte[] header = new byte[4];
        inputStream.read(header);
        int length = ByteBuffer.wrap(header).getInt();

        byte[] body = new byte[length];
        inputStream.read(body);

        return Message.parseFrom(body);
    }

    /**
     * 关闭连接
     */
    public synchronized void close() {
        try {
            if (outputStream != null) {
                outputStream.close();
            }
            if (inputStream != null) {
                inputStream.close();
            }
            if (socket != null) {
                socket.close();
            }
        } catch (IOException e) {
            logger.error("关闭连接时发生错误", e);
        }
    }
}
